using AutoMapper;
using MediatR;
using S.O.Domain.RBAC;
using S.O.Domain.Dto.Output;
using S.O.ErrorCode;
using S.O.Interstructrue.Base;
using S.O.Api.Read.Application.Command.Role;

namespace S.O.Api.Read.Application.Handler.Role
{
    public class GetRoleListHandler : IRequestHandler<GetRoleListCommand, APIPaging<GetRoleListDto>>
    {
        private readonly IBaseRepository<RoleModel> roleRepository;
        private readonly IBaseRepository<PermissionModel> permissionRepository;
        private readonly IBaseRepository<RolePermissionModel> roleperimissionRepository;
        private readonly IMapper mapper;
        private readonly ILogger<GetRoleListHandler> logger;

        public GetRoleListHandler(IBaseRepository<RoleModel> roleRepository, IBaseRepository<PermissionModel> permissionRepository, IBaseRepository<RolePermissionModel> roleperimissionRepository, IMapper mapper, ILogger<GetRoleListHandler> logger)
        {
            this.roleRepository = roleRepository;
            this.permissionRepository = permissionRepository;
            this.roleperimissionRepository = roleperimissionRepository;
            this.mapper = mapper;
            this.logger = logger;
        }
        /// <summary>
        /// 获取角色列表
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task<APIPaging<GetRoleListDto>> Handle(GetRoleListCommand request, CancellationToken cancellationToken)
        {
            APIPaging<GetRoleListDto> res = new APIPaging<GetRoleListDto>();
            var role = roleRepository.GetALL().Where(x => x.IsDeleted == false);
            var rolepermission = roleperimissionRepository.GetALL().Where(x => x.IsDeleted == false);
            var permission = permissionRepository.GetALL().Where(x => x.IsDeleted == false);
            if(request.RoleName != null)
            {
                role= role.Where(x => x.RoleName.Contains(request.RoleName));
            }
            
            // 先获取角色和权限的关联数据
            var rolePermData = from a in role
                       join b in rolepermission on a.Id equals b.RoleId
                       join c in permission on b.PermissionId equals c.Id
                       select new 
                       {
                           RoleId = a.Id,
                           RoleName = a.RoleName,
                           PermissionName = c.PermissionName,
                           PermissionId=b.PermissionId,
                           CreateTime = a.CreateTime,
                           IsEnable = a.IsEnable
                       };

            // 按角色分组，将每个角色拥有的权限名称存储到数组中
            var groupedData = rolePermData
                .GroupBy(x => new { x.RoleId, x.RoleName, x.CreateTime, x.IsEnable })
                .Select(g => new GetRoleListDto
                {
                    Id = g.Key.RoleId,
                    RoleId = g.Key.RoleId,
                    RoleName = g.Key.RoleName,
                    PermissionNames = g.Select(p => p.PermissionName).ToList(),
                    PermissionIds = g.Select(p => p.PermissionId).ToList(),
                    CreateTime = g.Key.CreateTime,
                    IsEnable = g.Key.IsEnable
                }).ToList();

            res.Code = APIEnums.Success;
            var data = groupedData.OrderByDescending(x => x.CreateTime).Skip((request.PageIndex - 1) * request.PageSize).Take(request.PageSize).ToList();
            res.PageDatas = data;
            res.TotalCount = groupedData.Count;
            res.Msg = "��ȡ��ɫ�б��ɹ�";
            logger.LogInformation("��ȡ��ɫ�б��ɹ�");
            return Task.FromResult(res);
        }
    }
}
